package modular {
	import ch.sfug.data.Set;
	
	import modular.module.Module;		

	/**
	 * @author mich
	 */
	public class ModuleSet {
		
		private var _items:Array;
		public var loader:ModuleSetLoader;

		public function ModuleSet( xml:XML ) {
			if( xml.name() == "ModuleSet" ) {
				this._items = new Array();
				parseXML( xml);
			} else {
				throw new Error( "please provide a ModuleSet xml node for the ModuleSet class not: " + xml.toString() );
			}
		}

		
		private function parseXML( xml:XML ):void {
			for each ( var mod_xml:XML in xml.children() ) {
				if( mod_xml.name() == "ModuleSetLoader" ) mod_xml.@["class"] = "modular.ModuleSetLoader";
				_items.push( new ModuleSetItem( mod_xml ) );
			}
		}


		public function createInstancesOn( msl:ModuleSetLoader ):void {
			for each ( var item:ModuleSetItem in _items ) {
				item.createInstanceOn( msl );
			}
		}
		
		public function clone():ModuleSet {
			return new ModuleSet( rawXML );
		}

		
		
		public function show():void {
			for each ( var item:ModuleSetItem in _items ) {
				item.show();
			}
			adjustDepths();
		}
		
		private function adjustDepths():void {
			for( var i:int = 0; i < _items.length; i++ ) {
				var mod:Module = ModuleSetItem( _items[ i ] ).module;
				if( loader.contains( mod ) ) loader.setChildIndex( mod, _items.length - 1 - i );
			}
		}
		
		public function hide( ):void {
			for each ( var item:ModuleSetItem in _items ) {
				item.hide();
			}
		}
		
		public function transferEqualModules( newSet:ModuleSet ):void {
			var temp:Array = _items.slice();
			for each ( var own:ModuleSetItem in temp ) {
				for each ( var foreign:ModuleSetItem in newSet.items ) {
					if( own.equals( foreign ) ) {
						foreign.transfer( own );
						removeItem( own );
					}
				}
			}
		}
		
		public function removeItem( msi:ModuleSetItem ):void {
			var i:Number = _items.length;
			while( _items[--i] != msi && i >-1 );
			if( i > -1 ) _items.splice( i, 1 );
		}

		public function get items():Array {
			return _items.slice();
		}

		
		public function getLibrariesToLoad():Set {
			var libs:Set = new Set();
			for each (var item:ModuleSetItem in _items ) {
				if( item.getLibrary() != "" && !Library.isLoaded( item.getLibrary()) ) libs.add( item.getLibrary() );
			}
			return libs;
		}
		
		public function getModuleByID( id:String ):Module {
			for each ( var item:ModuleSetItem in _items ) {
				var mod:Module = item.getModuleByID( id );
				if( mod != null ) return mod;
			}
			return null;
		}
		
		
		public function getModuleByClass( className:String ):Module {
			for each ( var item:ModuleSetItem in _items ) {
				var mod:Module = item.getModuleByClass( className );
				if( mod != null ) return mod;
			}
			return null;
		}

		public function get rawXML():XML {
			var xml:XML = <ModuleSet></ModuleSet>;
			for each ( var item:ModuleSetItem in _items ) {
				xml.appendChild( item.info.rawXML );
			}
			return xml;
		}
		
		public function destroy():void {
			for each ( var item:ModuleSetItem in _items ) {
				item.destroy();
			}
			_items = null;
			loader = null;
		}
	}
}
